﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Exentials.Xoox.Styles
{
    public class XFont : XElementBase
    {
        private XElement _font;

        private XElementVal<string> _name;
        private XElementVal<byte> _charset;
        private XElementVal<byte> _family;
        private XElementVal<bool> _bold;
        private XElementVal<bool> _italic;
        private XElementVal<bool> _strike;
        private XElementVal<bool> _outline;
        private XElementVal<bool> _shadow;
        private XElementVal<bool> _condense;
        private XElementVal<bool> _extend;
        private XColor _color;
        private XElementVal<double> _size;
        private XElementVal<XFontUnderline> _underline;
        private XElementVal<XFontVerticalAlign> _vertAlign;
        private XElementVal<XFontScheme> _scheme;

        //Excel 2007 requires the child elements to be in the following sequence: 
        // i, strike, condense, extend, outline, shadow, u, vertAlign, sz, color, name, family, charset, scheme.

        public XFont()
            : base("font")
        {
            this._font = this.GetXElement();            
        }

        public string Name
        {
            get
            {
                if (this._name == null) return string.Empty;
                return this._name.Val;
            }
            set
            {
                if (this._name == null)
                {
                    this._name = new XElementVal<string>("name");
                    this._font.Add(this._name.GetXElement());
                }
                this._name.Val = value;
            }
        }

        public byte Charset
        {
            get
            {
                if (this._charset == null) return 0;
                return this._charset.Val;
            }
            set
            {
                if (this._charset == null)
                {
                    this._charset = new XElementVal<byte>("charset");
                    _font.Add(this._charset.GetXElement());
                }
                this._charset.Val = value;
            }
        }

        public byte Family
        {
            get
            {
                if (this._family == null) return 0;
                return this._family.Val;
            }
            set
            {
                if (this._family == null)
                {
                    this._family = new XElementVal<byte>("family");
                    this._font.Add(this._family.GetXElement());
                }
                this._family.Val = value;
            }
        }

        public bool Bold
        {
            get
            {
                if (this._bold == null) return false;
                return this._bold.Val;
            }
            set
            {
                if (this._bold == null)
                {
                    this._bold = new XElementVal<bool>("b");
                    this._font.Add(this._bold.GetXElement());
                }
                this._bold.Val = value;
            }
        }

        public bool Italic
        {
            get
            {
                if (this._italic == null) return false;
                return this._italic.Val;
            }
            set
            {
                if (this._italic == null)
                {
                    this._italic = new XElementVal<bool>("i");
                    this._font.Add(this._italic.GetXElement());
                }
                this._italic.Val = value;
            }
        }

        public bool Strike
        {
            get
            {
                if (this._strike == null) return false;
                return this._strike.Val;
            }
            set
            {
                if (this._strike == null)
                {
                    this._strike = new XElementVal<bool>("strike");
                    this._font.Add(this._strike.GetXElement());
                }
                this._strike.Val = value;
            }
        }

        public bool Outline
        {
            get
            {
                if (this._outline == null) return false;
                return this._outline.Val;
            }
            set
            {
                if (this._outline == null)
                {
                    this._outline = new XElementVal<bool>("outline");
                    this._font.Add(this._outline.GetXElement());
                }
                this._outline.Val = value;
            }
        }

        public bool Shadow
        {
            get
            {
                if (this._shadow == null) return false;
                return this._shadow.Val;
            }
            set
            {
                if (this._shadow == null)
                {
                    this._shadow = new XElementVal<bool>("shadow");
                    this._font.Add(this._shadow.GetXElement());
                }
                this._shadow.Val = value;
            }
        }

        public bool Condense
        {
            get
            {
                if (this._condense == null) return false;
                return this._condense.Val;
            }
            set
            {
                if (_condense == null)
                {
                    this._condense = new XElementVal<bool>("condense");
                    this._font.Add(this._condense.GetXElement());
                }
                this._condense.Val = value;
            }
        }

        public bool Extend
        {
            get
            {
                if (this._extend == null) return false;
                return this._extend.Val;
            }
            set
            {
                if (this._extend == null)
                {
                    this._extend = new XElementVal<bool>("extend");
                    this._font.Add(this._extend.GetXElement());
                }
                this._extend.Val = value;
            }
        }

        public XColor Color
        {
            get
            {
                if (this._color == null) this._color = new XColor("color");
                return this._color;
            }
        }

        public double Size
        {
            get
            {
                if (this._size == null) return 1;
                return this._size.Val;
            }
            set
            {
                if (this._size == null)
                {
                    this._size = new XElementVal<double>("sz");
                    this._font.Add(this._size.GetXElement());
                }
                this._size.Val = value;
            }
        }

        public XFontUnderline Underline
        {
            get
            {
                if (this._underline == null) return XFontUnderline.none;
                return this._underline.Val;
            }
            set
            {
                if (this._underline == null)
                {
                    this._underline = new XElementVal<XFontUnderline>("u");
                    this._font.Add(this._underline.GetXElement());
                }
                this._underline.Val = value;
            }            
        }

        public XFontVerticalAlign VertAlign
        {
            get
            {
                if (this._vertAlign == null) return XFontVerticalAlign.Baseline;
                return this._vertAlign.Val;
            }
            set
            {
                if (this._underline == null)
                {
                    this._vertAlign = new XElementVal<XFontVerticalAlign>("vertAlign");
                    this._font.Add(this._vertAlign.GetXElement());
                }
                this._vertAlign.Val = value;
            }
        }

        public XFontScheme Scheme
        {
            get
            {
                if (this._scheme == null) return XFontScheme.none;
                return this._scheme.Val;
            }
            set
            {
                if (this._scheme == null)
                {
                    this._scheme = new XElementVal<XFontScheme>("scheme");
                    this._font.Add(this._scheme.GetXElement());
                }
                this._scheme.Val = value;
            }
        }
    }
}
